# -*- coding: utf-8 -*-
# @time:2025/4/4:21:33
# @IDE:PyCharm

from PIL import Image
import os
import math
from .utils import _save_image, _handle_processing_error


def process_single_page(input_dir, output_dir, book_name, image_files, margin, dpi, save_format):
    processed_count = 0
    output_files = []
    total = len(image_files)
    for i, img_file in enumerate(image_files):
        print(f"处理单页: {i+1}/{total} ({img_file})")
        img = None
        final_img = None
        try:
            img_path = os.path.join(input_dir, img_file)
            img = Image.open(img_path)
            img.load()
            if margin > 0:
                width, height = img.size
                mode = img.mode
                bg_color = "white"
                if 'A' in img.getbands():
                    mode = 'RGBA'
                    bg_color = (255, 255, 255, 255)
                elif mode in ['P', 'L', 'LA']:
                    mode = 'RGB'
                elif mode != 'RGB':
                    mode = 'RGB'
                new_width = width + margin
                new_img_bg = Image.new(mode, (new_width, height), bg_color)
                img_to_paste = img if img.mode == mode else img.convert(mode)
                new_img_bg.paste(img_to_paste, (0, 0))
                final_img = new_img_bg
            else:
                final_img = img
            output_filename = f"{book_name}_{i:04d}.{save_format}"
            output_path = os.path.join(output_dir, output_filename)
            img_to_save = final_img.copy() if final_img is img else final_img
            _save_image(img_to_save, output_path, dpi, save_format)
            if img_to_save is not final_img:
                img_to_save.close()
            output_files.append(output_path)
            processed_count += 1
        except Exception as e:
            _handle_processing_error(e, img_file)
        finally:
            if img:
                img.close()
            if final_img and final_img is not img:
                final_img.close()
    return processed_count, output_files


def process_double_page(input_dir, output_dir, book_name, image_files, center_margin, dpi, save_format):
    processed_count = 0
    output_files = []
    num_images = len(image_files)
    total_pairs = math.ceil(num_images / 2)
    for i in range(0, num_images, 2):
        pair_index = i // 2
        left_img_file = image_files[i]
        right_img_file = image_files[i + 1] if (i + 1) < num_images else None
        print(f"处理双页: {pair_index + 1}/{total_pairs}")
        left_img = None
        right_img = None
        new_img = None
        try:
            left_img_path = os.path.join(input_dir, left_img_file)
            left_img = Image.open(left_img_path)
            left_img.load()
            if right_img_file:
                right_img_path = os.path.join(input_dir, right_img_file)
                right_img = Image.open(right_img_path)
                right_img.load()
            else:
                lw, lh = left_img.size
                blank_mode = left_img.mode if left_img.mode in ['RGB', 'RGBA', 'L'] else 'RGB'
                if blank_mode == 'L':
                    bg_color = 255
                elif blank_mode == 'RGBA':
                    bg_color = (255, 255, 255, 255)
                else:
                    blank_mode = 'RGB'
                    bg_color = (255, 255, 255)
                right_img = Image.new(blank_mode, (lw, lh), bg_color)

            left_w, left_h = left_img.size
            right_w, right_h = right_img.size
            target_height = max(left_h, right_h)
            resample_method = Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.ANTIALIAS
            if left_h != target_height:
                ratio = target_height / left_h
                new_w = int(left_w * ratio)
                left_img_resized = left_img.resize((new_w, target_height), resample_method)
                left_img.close()
                left_img = left_img_resized
                left_w = new_w
            if right_h != target_height:
                ratio = target_height / right_h
                new_w = int(right_w * ratio)
                right_img_resized = right_img.resize((new_w, target_height), resample_method)
                right_img.close()
                right_img = right_img_resized
                right_w = new_w
            total_width = left_w + center_margin + right_w
            combined_mode = 'RGB'
            if 'A' in left_img.getbands() or 'A' in right_img.getbands():
                combined_mode = 'RGBA'
            if left_img.mode != combined_mode:
                left_img = left_img.convert(combined_mode)
            if right_img.mode != combined_mode:
                right_img = right_img.convert(combined_mode)
            bg_color = (255, 255, 255, 255) if combined_mode == 'RGBA' else (255, 255, 255)
            new_img = Image.new(combined_mode, (total_width, target_height), bg_color)
            new_img.paste(left_img, (0, 0))
            new_img.paste(right_img, (left_w + center_margin, 0))
            output_filename = f"{book_name}_{pair_index:04d}.{save_format}"
            output_path = os.path.join(output_dir, output_filename)
            _save_image(new_img, output_path, dpi, save_format)
            output_files.append(output_path)
            processed_count += 1
        except Exception as e:
            _handle_processing_error(e, f"{left_img_file} / {right_img_file or 'N/A'}")
        finally:
            if left_img:
                left_img.close()
            if right_img:
                right_img.close()
            if new_img:
                new_img.close()
    return processed_count, output_files


def process_by_binding_simple(input_dir, output_dir, book_name, image_files, center_margin, ground_height, dpi, save_format, points):
    processed_count = 0
    output_files = []
    num_images = len(image_files)
    total_pairs = math.ceil(num_images / 2)
    for i in range(0, num_images, 2):
        pair_index = i // 2
        left_img_file = image_files[i]
        right_img_file = image_files[i + 1] if (i + 1) < num_images else None
        print(f"处理装帧页: {pair_index + 1}/{total_pairs}")
        left_img = None
        right_img = None
        final_img = None
        try:
            left_img_path = os.path.join(input_dir, left_img_file)
            left_img = Image.open(left_img_path)
            left_img.load()
            if right_img_file:
                right_img_path = os.path.join(input_dir, right_img_file)
                right_img = Image.open(right_img_path)
                right_img.load()
            else:
                lw, lh = left_img.size
                blank_mode = left_img.mode if left_img.mode in ['RGB', 'RGBA', 'L'] else 'RGB'
                if blank_mode == 'L':
                    bg_color = 255
                elif blank_mode == 'RGBA':
                    bg_color = (255, 255, 255, 255)
                else:
                    blank_mode = 'RGB'
                    bg_color = (255, 255, 255)
                right_img = Image.new(blank_mode, (lw, lh), bg_color)

            left_w, left_h = left_img.size
            right_w, right_h = right_img.size
            target_content_height = max(left_h, right_h)
            resample_method = Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.ANTIALIAS
            if left_h != target_content_height:
                ratio = target_content_height / left_h
                new_w = int(left_w * ratio)
                left_img_resized = left_img.resize((new_w, target_content_height), resample_method)
                left_img.close()
                left_img = left_img_resized
                left_w = new_w
            if right_h != target_content_height:
                ratio = target_content_height / right_h
                new_w = int(right_w * ratio)
                right_img_resized = right_img.resize((new_w, target_content_height), resample_method)
                right_img.close()
                right_img = right_img_resized
                right_w = new_w
            total_width = left_w + center_margin + right_w
            total_height = target_content_height + ground_height
            combined_mode = 'RGB'
            if 'A' in left_img.getbands() or 'A' in right_img.getbands():
                combined_mode = 'RGBA'
            if left_img.mode != combined_mode:
                left_img = left_img.convert(combined_mode)
            if right_img.mode != combined_mode:
                right_img = right_img.convert(combined_mode)
            bg_color = (255, 255, 255, 255) if combined_mode == 'RGBA' else (255, 255, 255)
            final_img = Image.new(combined_mode, (total_width, total_height), bg_color)
            final_img.paste(left_img, (0, 0))
            final_img.paste(right_img, (left_w + center_margin, 0))
            output_filename = f"{book_name}_{pair_index:04d}.{save_format}"
            output_path = os.path.join(output_dir, output_filename)
            _save_image(final_img, output_path, dpi, save_format)
            output_files.append(output_path)
            processed_count += 1
        except Exception as e:
            _handle_processing_error(e, f"{left_img_file} / {right_img_file or 'N/A'}")
        finally:
            if left_img:
                left_img.close()
            if right_img:
                right_img.close()
            if final_img:
                final_img.close()
    return processed_count, output_files


def process_by_points_align_scale(input_dir, output_dir, book_name, image_files, center_margin, ground_height, dpi, save_format, points_relative_y):
    processed_count = 0
    output_files = []
    num_images = len(image_files)
    total_pairs = math.ceil(num_images / 2)
    y_p1, y_p2, y_p3, y_p4 = points_relative_y[0], points_relative_y[1], points_relative_y[2], points_relative_y[3]
    for i in range(0, num_images, 2):
        pair_index = i // 2
        left_img_file = image_files[i]
        right_img_file = image_files[i + 1] if (i + 1) < num_images else None
        print(f"处理采样点页: {pair_index + 1}/{total_pairs}")
        left_img = None
        right_img = None
        final_img = None
        try:
            left_img_path = os.path.join(input_dir, left_img_file)
            left_img = Image.open(left_img_path)
            left_img.load()
            if right_img_file:
                right_img_path = os.path.join(input_dir, right_img_file)
                right_img = Image.open(right_img_path)
                right_img.load()
                y_p3_eff, y_p4_eff = y_p3, y_p4
                is_right_blank = False
            else:
                lw, lh = left_img.size
                blank_mode = left_img.mode if left_img.mode in ['RGB', 'RGBA', 'L'] else 'RGB'
                if blank_mode == 'L':
                    bg_color = 255
                elif blank_mode == 'RGBA':
                    bg_color = (255, 255, 255, 255)
                else:
                    blank_mode = 'RGB'
                    bg_color = (255, 255, 255)
                right_img = Image.new(blank_mode, (lw, lh), bg_color)
                y_p3_eff, y_p4_eff = 0.0, 1.0
                is_right_blank = True

            left_w, left_h = left_img.size
            right_w, right_h = right_img.size
            Ly1_abs = left_h * y_p1
            Ly2_abs = left_h * y_p2
            Ry1_abs = right_h * y_p3_eff
            Ry2_abs = right_h * y_p4_eff
            L_dist = abs(Ly1_abs - Ly2_abs)
            R_dist = abs(Ry1_abs - Ry2_abs)
            scale_y = 1.0
            if R_dist > 1e-6 and L_dist > 1e-6 and not is_right_blank:
                scale_y = L_dist / R_dist
            scale_y = max(0.1, min(10.0, scale_y))
            if abs(scale_y - 1.0) > 1e-6 and not is_right_blank:
                new_rh = int(right_h * scale_y)
                new_rw = int(right_w * scale_y)
                if new_rh > 0 and new_rw > 0:
                    resample_method = Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.ANTIALIAS
                    print(f"Scaling right image by {scale_y:.3f} to ({new_rw}x{new_rh})")
                    right_img_scaled = right_img.resize((new_rw, new_rh), resample_method)
                    right_img.close()
                    right_img = right_img_scaled
                    right_w, right_h = new_rw, new_rh
                    Ry1_abs *= scale_y
                    Ry2_abs *= scale_y
                else:
                    print(f"Warning: Scaling factor {scale_y} resulted in zero dimension for right image. Skipping scaling.")
            elif is_right_blank:
                if right_h != left_h:
                    right_img_scaled = right_img.resize((right_w, left_h))
                    right_img.close()
                    right_img = right_img_scaled
                    right_h = left_h

            y_offset = Ly1_abs - Ry1_abs
            paste_y_left = max(0, -y_offset)
            paste_y_right = max(0, y_offset)
            total_width = left_w + center_margin + right_w
            content_height = max(paste_y_left + left_h, paste_y_right + right_h)
            total_height = int(content_height + ground_height)
            combined_mode = 'RGB'
            bg_color = (255, 255, 255)
            if 'A' in left_img.getbands() or ('A' in right_img.getbands() and not is_right_blank):
                combined_mode = 'RGBA'
                bg_color = (255, 255, 255, 255)
            if left_img.mode != combined_mode:
                left_img = left_img.convert(combined_mode)
            if right_img.mode != combined_mode:
                right_img = right_img.convert(combined_mode)
            final_img = Image.new(combined_mode, (total_width, total_height), bg_color)
            final_img.paste(left_img, (0, int(paste_y_left)))
            final_img.paste(right_img, (left_w + center_margin, int(paste_y_right)))
            output_filename = f"{book_name}_{pair_index:04d}.{save_format}"
            output_path = os.path.join(output_dir, output_filename)
            _save_image(final_img, output_path, dpi, save_format)
            output_files.append(output_path)
            processed_count += 1
        except Exception as e:
            _handle_processing_error(e, f"{left_img_file} / {right_img_file or 'N/A'}")
        finally:
            if left_img:
                left_img.close()
            if right_img:
                right_img.close()
            if final_img:
                final_img.close()
    return processed_count, output_files